2023/12/234002字符
文件流
流:数据的流动,从一个地方缓缓流到另一个地方。
文件流:内存数据和磁盘数据之间的流动
- 可读流:数据从源头流向内存
- 可写流:数据从内存流向源头
- 双工流:数据可从源头流向内存,也可从内存流向源头
可读流
const fs = require('fs');
const path = require('path');
const filename = path.resolve(__dirname, './pack.json');
const rs = fs.createReadStream(filename, {
encoding: 'utf-8', // 默认为 buffer
highWaterMark: 1, // 受 encoding 影响,encoding 为 null 时单位为字节,encoding 为 utf-8 时单位为字符
});
文件读取事件
- open:文件打开
- error:出现错误
- data:每读到一部分数据出发一次
- end:文件读取完毕
- close:文件关闭
- resume:文件读取暂停时触发
- resume:文件恢复读取时触发
rs.on('open', () => {
console.log('文件被打开');
});
rs.on('data', chunk => {
console.log(chunk); // 参数为每次读到的数据
rs.pause(); // 暂停读取
});
rs.on('pause', () => {
console.log('文件读取暂停');
setTimeout(() => {
rs.resume(); // 继续读取
}, 1000);
});
rs.on('resume', () => {
console.log('继续读取问价');
});
可写流
const fs = require('fs');
const path = require('path');
const filename = path.resolve(__dirname, './data/note.md');
const ws = fs.createWriteStream(filename, {
encoding: 'utf-8', // 默认为 buffer
highWaterMark: 3, // 不会受 encoding 影响,一次写入的字节数
});
文件写入事件
- open:文件打开
- error:出现错误
- close:文件关闭
- write:文件写入
- end:写入文件结束触发(需手动触发)
- drain:写入队列清空时触发
const flag = ws.write('hello'); console.log(flag); //--> false
ws.write() 返回 true 表示下次调用可直接写入,为 false 表示写入内容 >= highWaterMark 规定的大小,超出部分暂时存在内存当中,产生背压
写一个可以持续写入数据并且不会产生背压的函数
const fs = require('fs');
const path = require('path');
/**
* @param {string} filename 写入地址
* @param {string} content 写入的重复内容
* @param {number} content 要写入的文件大小
*/
function writeFile (filename, content, size = 1024 * 1024 * 5) {
const ws = fs.createWriteStream(filename, {
encoding: 'utf-8', // 默认为 buffer
highWaterMark: 16 * 1024, // 不会受 encoding 影响,一次写入的字节数
});
let i = 0;
function write () {
let flag = true;
while (i < size && flag) {
flag = ws.write(content);
i ++;
}
}
write();
ws.on('drain', () => { // 写入队列清空时触发 drain 事件
write();
})
}
const filename = path.resolve(__dirname, './data/note.md');
writeFile(filename, 'Hello, word! ');
大型文件复制
const fs = require('fs');
const path = require('path');
async function copyFile () {
const from = path.resolve(__dirname, './data/note.md');
const to = path.resolve(__dirname, './data/note2.md');
console.time();
const rs = fs.createReadStream(from);
const ws = fs.createWriteStream(to);
rs.pipe(ws); // 通道写入,== 下面的代码
// rs.on('data', chunk => {
// // 读到一部分数据则暂停
// const flag = ws.write(chunk);
// if (!flag) {
// rs.pause();
// }
// });
// // 清空队列后继续读取文件
// ws.on('drain', () => {
// rs.resume();
// });
rs.on('close', () => {
ws.end(); // 手动结束写入操作
console.timeEnd();
})
}
copyFile();